package hk.org.ha.cdars.job;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import hk.org.ha.cdars.datacontext.BisDataContext;
import hk.org.ha.cdars.datacontext.BisDataContextImpl;
import hk.org.ha.cdars.datacontext.BisDataContext.Criteria;
import hk.org.ha.cdars.datacontext.BisDataContext.G1CriterialNode;
import hk.org.ha.cdars.datacontext.BisDataContext.G2CriterialNode;
import hk.org.ha.cdars.datacontext.BisDataContext.IpStep2ComboList;
import lava.rt.common.ReflectCommon;

public abstract class CheckJob<R> {
	
	
	public enum Flag{
		相同("same"),差異("diff"),不存在("missing");
		
		public final String code;

		private Flag(String code) {
			this.code = code;
		}
		
		
	}
	
	private int jobNo;
	
	@Autowired
	protected BisDataContextImpl dataContext;

	protected BisDataContext.Criteria CR;
	
	public abstract List<R> check() throws Exception;
	
	

	public int getJobNo() {
		return jobNo;
	}

	public void setJobNo(int jobNo) {
		this.jobNo = jobNo;
	}
	
	
	
	protected String getNodeType(G2CriterialNode node) {
		// TODO Auto-generated method stub
		String ret=node.getFunctionCode();
		return ret;
	}
	
	
	protected String getNodeType(G1CriterialNode node) {
		// TODO Auto-generated method stub
		String ret=node.getFunctionCode();
		return ret;
	}
	
	
	public static int compare(G1CriterialNode g1node,G2CriterialNode g2node,List<String> diffInfos) {
		int ret=0;
		String[] keys=new String[] {
				Criteria.criteriaType.column
		        ,Criteria.columnId.column
		        ,Criteria.functionCode.column
		        ,Criteria.groupId.column
		        ,Criteria.treeType.column
		        ,Criteria.type.column
		        ,Criteria.itemCode.column
		};
		Map<String, Field> g1FieldMap=ReflectCommon.getAllDeclaredFieldMap(G1CriterialNode.class)
				,g2FieldMap=ReflectCommon.getAllDeclaredFieldMap(G2CriterialNode.class);
				;
		for(String key:keys) {
			Field g1Field=g1FieldMap.get(key)
					,g2Field=g2FieldMap.get(key);
					;
			g1Field.setAccessible(true);
			g2Field.setAccessible(true);
		    try {
		    	Object g1Val=g1Field.get(g1node)
						,g2Val=g2Field.get(g2node);
						;
		    	if(!Objects.equals(g1Val, g2Val)) {
		    		String diffMsg=key+":"+g1Val+"!="+g2Val+"";
		    		diffInfos.add(diffMsg);
		    		ret++;
		    	}
		    }catch(Exception ex) {
		    	diffInfos.add(key+":"+ex.getMessage());
		    	ret++;
		    }
			
		}
		
		return ret;
	}
	
	
	protected  int compare(G1CriterialNode source, IpStep2ComboList target, List<String> diffMsgs) {
		// TODO Auto-generated method stub
		int ret=0;
		
		if(!Objects.equals(format(source.getFunctionCode()), format(target.getNodeType()))) {
			String diffMsg="nodeType:"+source.getFunctionCode()+"!="+target.getNodeType()+"";
			diffMsgs.add(diffMsg);
    		ret++;
		}
		return ret;
	}
	
	
	
	



	protected  int compare(G2CriterialNode source, IpStep2ComboList target, List<String> diffMsgs) {
		// TODO Auto-generated method stub
		int ret=0;
		if(!Objects.equals(format(source.getFunctionCode()), format(target.getNodeType()))) {
			String diffMsg="nodeType:"+source.getFunctionCode()+"!="+target.getNodeType()+"";
			diffMsgs.add(diffMsg);
    		ret++;
		}
		return ret;
	}
	
	
	
	private String format(String val) {
		// TODO Auto-generated method stub
		String ret=val;
		if(val==null) {
			ret="";
		}
		else if(Objects.equals("null", val)) {
			ret="";
		}
		return ret;
	}
	
}
